package com.shenfa.service.compose;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.gmc.util.netserver.NetServerUtil;
import net.gmc.util.netserver.command.CommandMaker;
import net.gmc.util.netserver.control.NetServerFlowControl;
import net.gmc.util.netserver.flow.NetServerFlowInterface;
import net.gmc.util.netserver.runcommand.NetServerConnection;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.shenfa.bean.BillStencilSub;
import com.shenfa.bean.PaperCityCrd;
import com.shenfa.bean.PaperInfo;
import com.shenfa.bean.Template;
import com.shenfa.dao.BillStencilDao;
import com.shenfa.dao.EpibCityDao;
import com.shenfa.dao.PaperDao;
import com.shenfa.dao.TemplateDao;
import com.shenfa.dao.compose.MakeComposeDao;
import com.shenfa.dao.xml.MakeXmlDao;
import com.shenfa.tools.SteelDate;
import com.shenfa.util.FileUtil;

public class MakeComposeService {
	
	private Logger log = Logger.getLogger(MakeComposeService.class);
	
	@Autowired
	private MakeComposeDao makeComposeDao;	//查询XML名称及路径
	@Autowired
	private TemplateDao templateDao;		//查询模板路径
	@Autowired
	private EpibCityDao epibCityDao;		//查询外包商打印类型
	@Autowired
	private MakeXmlDao makeXmlDao;			//查询JOB文件路径
	@Autowired
	private BillStencilDao billStencilDao;	//查询数据模块名称
	@Autowired
	private PaperDao paperDao;				//查询预印纸底板路径
	
	private Template template;
	private PaperCityCrd paperCityCrd = new PaperCityCrd();
	private BillStencilSub billStencilSub = new BillStencilSub();
	
	private Map<String, String> xmlLog;		//XML日志
	private HashMap<String, Object> composeLog;	//账单构造对象
	private Map<String, String> xmlData;
	private Map<String, String> htmlMap = new HashMap<String, String>();
	private FileUtil fileUtil;
	
	private boolean image_flag = true;			//预印纸底板图片路径(用于判断是否上传)
	private String filepath = null;
	
	private ArrayList<HashMap<String, Object>> pCompose = new ArrayList<HashMap<String,Object>>();	//实体账单集合
	private ArrayList<HashMap<String, Object>> eCompose = new ArrayList<HashMap<String,Object>>();	//电子账单集合
	
	/**
	 * 特殊XML状态修改
	 * @param map
	 */
	private void updState(Map<String, String> map, String str){
		if(str.length() == 1)
			map.put("state", str);
		else 
			map.put("billfilename", str);
		map.put("endtime", SteelDate.getDate(SteelDate.YYYY_MM_DD_HH_MM_SS, new Date()));
		int flag = makeComposeDao.updXmlLogState(map);
		if(flag == 1){
			log.debug("XML文件状态修改异常。==>>状态："+map.get("state")+", 文件名："+xmlLog.get("filename"));
		}
	}
	
	/**
	 * 正常XML状态修改
	 * @param map
	 * @param str
	 */
	private void updComposeState(String name, String state){
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("filename", name);
		map.put("state", state);
		map.put("endtime", SteelDate.getDate(SteelDate.YYYY_MM_DD_HH_MM_SS, new Date()));
		int flag = makeComposeDao.updComposeLogState(map);
		if(flag == 1){
			log.debug("XML文件状态修改异常。==>>状态："+state+", 文件名："+name);
		}
	}
	
	/**
	 * 根据用户ID，查询对应的XML文件组装数据合成账单
	 * 
	 * 特殊账单合成
	 * 
	 * @param userid
	 * @throws Exception 
	 */
	public void makeCompose(String userid) throws Exception{
		//查询对应用户合成成功的XML文件集合
		List<Map<String, String>> listxml = makeComposeDao.getListXmlByUserid(userid);
		//若用户未有对应生成成功的XML文件，结束操作返回
		int len1 = listxml.size();
		if(len1 == 0) {
			log.debug("==>>查找XML文件列表异常.");
			return;
		}
		//若已查询到生成成功的XML文件，则循环构造对象
		for(int i = 0; i < len1; i++){
			template = new Template();
			//修改XML状态未账单生产中,修改失败打印日志
			xmlLog = listxml.get(i);
			this.updState(xmlLog, "3");
			String fileName = xmlLog.get("filename");
			//开始构造对象
			composeLog = new HashMap<String, Object>();
			xmlData = new HashMap<String, String>();
			template.setCardid(xmlLog.get("cardid"));
			if(null == xmlLog.get("epibolyno")) {	//外包商为空，则为电子账单
				//根据卡号和类型查询模板
				template.setType("2");	
				template = templateDao.getObject(template);
				if(null == template) {	//未查找到对应模板，打印日志并修改Xml状态
					log.debug("模板查询异常。==>>卡产品："+xmlLog.get("cardid")+", 文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				//1.模板全路径
				composeLog.put("wfd", template.getStorpath());	
				//2.数据模块名称
				billStencilSub.setStencilno(template.getId());
				String listname = billStencilDao.getMinStencilSubName(billStencilSub);
				if(null == listname) {	//未查找到模板对应数据模块，打印日志并修改Xml状态
					log.debug("数据模块查询异常。==>>模板ID："+template.getId()+", 文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				xmlData.put("dif1", listname);			
				//3.数据模块全路径
				xmlData.put("dif2", fileName);	
				//4.数据模板对象
				composeLog.put("dif", xmlData);					
				//5.防火区目录
				String matterpath = makeXmlDao.getConfig().get("MATTERPATH");
				if(null == matterpath) {	//未查找到防火区配置目录，打印日志并修改Xml状态
					log.debug("防火区配置目录查询异常。==>>文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				composeLog.put("matterPath", matterpath);	
				//6.打印类型，正常0
				composeLog.put("printFlag", 0);								
				//7.电子账单标题
				String emailtitle = makeXmlDao.getConfig().get("EMAILTITLE");
				if(null == emailtitle) {	//未查找到电子账单标题，打印日志并修改Xml状态
					log.debug("电子账单标题查询异常。==>>文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				composeLog.put("EmailTitle", emailtitle);					
				//8.输出类型，HTML
				composeLog.put("e", CommandMaker.OUTPUT_TYPE_HTML);			
				//9.HTML生成路径，不带后缀，为生成索引文件准备  HTML_xxxX_xxxx_xxx
				String fn = fileName;
				fn = fn.substring(fn.lastIndexOf("/")+1,fn.lastIndexOf("."));
				filepath = fileName.replace(".xml", "").replace("/XML/", "/HTML/"+userid+"/"+fn+"/");
				fn = filepath.substring(0, filepath.lastIndexOf("/")+1);
				File f = new File(fn);
				if(!f.exists()) {
					f.mkdirs();
				}
				htmlMap.put(fileName, fn);
				composeLog.put("productionPath", filepath);
				//10.HTML生成路径，带后缀(.html)
				composeLog.put("f", filepath + "_%06g.html");
				//11.job路径
				composeLog.put("c", template.getJobpath());
				//12.警告配置路径
				String warningpath = makeXmlDao.getConfig().get("WARNINGPATH");
				if(null == warningpath) {	//未查找到警告配置路径，打印日志并修改Xml状态
					log.debug("警告配置路径查询异常。==>>文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				composeLog.put("warningconfig", warningpath);
				eCompose.add(composeLog);
			} else {	//实体账单对象构造
				image_flag = true;
				template.setType("1");
				//根据卡号和类型查询模板
				template = templateDao.getObject(template);
				if(null == template) {	//未查找到对应模板，打印日志并修改Xml状态
					log.debug("模板查询异常。==>>卡产品："+xmlLog.get("cardid")+", 文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				//1.模板全路径
				composeLog.put("wfd", template.getStorpath());	
				//2.数据模块名称
				billStencilSub.setStencilno(template.getId());
				String listname = billStencilDao.getMinStencilSubName(billStencilSub);
				if(null == listname) {	//未查找到模板对应数据模块，打印日志并修改Xml状态
					log.debug("数据模块查询异常。==>>模板ID："+template.getId()+", 文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				xmlData.put("dif1", listname);			
				//3.数据模块全路径
				xmlData.put("dif2", fileName);	
				//4.数据模板对象
				composeLog.put("dif", xmlData);					
				//5.外包商打印类型
				paperCityCrd.setCard_no(xmlLog.get("cardid"));
				paperCityCrd.setBusinpnt_no(xmlLog.get("epibolyno"));
				List<PaperCityCrd> lp = epibCityDao.getList(paperCityCrd, 0, 1);
				if(null == lp) {	//未查找到外包商打印类型，打印日志并修改Xml状态
					log.debug("外包商打印类型查询异常。==>>卡产品ID："+xmlLog.get("cardid")+", 外包商ID："
							+xmlLog.get("epibolyno")+", 文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				paperCityCrd = lp.get(0);
				composeLog.put("printMode", paperCityCrd.getPrint_type());	
				//6.打印类型，正常0
				composeLog.put("printFlag", 0);								
				//7.模板标识，带底板1
				composeLog.put("templateFlag", 1);					
				//8.输出类型，PDF
				composeLog.put("e", CommandMaker.OUTPUT_TYPE_PDF);			
				//9.PDF生成路径，不带后缀，为生成索引文件准备
				filepath = fileName.replace(".xml", "").replace("/XML/", "/PDF/");
				composeLog.put("productionPath", filepath);
				//10.PDF生成路径，带后缀(.pdf)
				composeLog.put("f", filepath+".pdf");
				this.updState(xmlLog, filepath+".pdf");
				//11.job路径
				String jobpath = makeXmlDao.getConfig().get("SPEC_JOB");
				if(null == jobpath) {	//未查找到job路径，打印日志并修改Xml状态
					log.debug("job路径查询异常。==>>文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				composeLog.put("c", jobpath);
				//12.警告配置路径
				String warningpath = makeXmlDao.getConfig().get("WARNINGPATH");
				if(null == warningpath) {	//未查找到警告配置路径，打印日志并修改Xml状态
					log.debug("警告配置路径查询异常。==>>文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				composeLog.put("warningconfig", warningpath);
				//12.预印纸底板路径
				Map<String, String> prepPaperPath = new HashMap<String, String>();
				List<PaperInfo> listp = paperDao.queryPaperInfoBypaperNo(xmlLog.get("paperno"));
				int len3 = listp.size();
				if(len3 == 0) {	//未查找到预印纸底板路径，打印日志并修改Xml状态
					log.debug("预印纸底板路径查询异常。==>>文件名："+fileName);
					this.updState(xmlLog, "4");
					continue;
				}
				for(int k = 0; k < len3; k++) {
					String imagepath = listp.get(k).getFront();
					if("" == imagepath) {	//未查找到预印纸底板路径，打印日志并修改Xml状态
						log.debug("预印纸底板路径查询异常。==>>预印纸编号："+listp.get(k).getId()+", 底板编号："+listp.get(k).getBg_no());
						this.updState(xmlLog, "4");
						image_flag = false;
						break;
					}
					prepPaperPath.put("prePaperPath"+(k+1), imagepath);
				}
				if(!image_flag){
					continue;
				}
				composeLog.put("prePaperPath", prepPaperPath);
				pCompose.add(composeLog); 
			}
		}
		NetServerUtil nsu = null;
		NetServerFlowControl control = null;
		NetServerFlowInterface runnerFlow = null;
		NetServerConnection connectionItem = null;
		fileUtil = new FileUtil();
		for(int i = 0; i < 2; i++) {
			if(i == 1 && null != eCompose) {		//电子账单传入参数
				nsu = new NetServerUtil(eCompose);
			} else if(i == 2 && null != pCompose) {	//纸质账单传入参数
				nsu = new NetServerUtil(pCompose);
			} else {
				continue;
			}
			//电子账单合成调用开始
			control = nsu.start();
			for(int j = 0; j < control.getNetServerFlowSize(); j++){
				runnerFlow = control.getNetServerFlow(j);
				connectionItem = runnerFlow.getNetServerConnection();
				boolean runSucc = runnerFlow.runSuccess();
				String resultState = "成功";
				if(!runSucc) {
					resultState = "失败";
					if(runnerFlow.lastJobMessage().contains("0030:Nothing to print.")) {
						log.debug("Nothing to print.fileindex flag write is [already pass]");
						resultState = "已过滤";
					}
				}
				String xmlFileName = runnerFlow.getNameItem("xmlName");
				//获取Xml数据名称
				log.debug("xml name is ==>>"+xmlFileName);
				//端口，job运行信息
				log.debug(connectionItem.getParameter("port")+"job run info ==>>"+runnerFlow.lastJobMessage());
				//修改XML状态未账单生产中
				xmlLog = new HashMap<String, String>();
				xmlLog.put("filename", xmlFileName);
				if("已过滤".equals(resultState)) {		//已过滤
					this.updState(xmlLog, "6");
				} else if("成功".equals(resultState)) {	//生成成功
					this.updState(xmlLog, "5");
					if(i == 1) {
						fileUtil.doZip(htmlMap.get(xmlFileName));
						this.updState(xmlLog, htmlMap.get(xmlFileName));
					}
				} else if("失败".equals(resultState)) {	//生成失败
					this.updState(xmlLog, "4");
				}
				
			}
		}
	}
	
	/**
	 * 
	 * 正常账单合成
	 * 
	 * @param fileName
	 * @return 返回操作结果
	 * 			0成功，1XML错误，2模板错误，3数据模块错误，4
	 */
	@SuppressWarnings("unchecked")
	public String makeCompose1(HashMap map) throws Exception{
		String logName = (String)map.get("fileName");
		Map<String, String> xmlLog = makeComposeDao.getXmlByFileName(map);
		if(null == xmlLog) {
			log.debug("==>>查找XML文件异常。==>>文件名："+logName);
			return "1";
		}
		String fileName = xmlLog.get("filename");
		template = new Template();
		composeLog = new HashMap<String, Object>();
		xmlData = new HashMap<String, String>();
		template.setCardid(xmlLog.get("cardid"));

		if(null == xmlLog.get("epibolyno")) {	//外包商为空，则为电子账单
			template.setType("2");	
			template = templateDao.getObject(template);
			if(null == template) {
				log.debug("模板查询异常。==>>卡产品：" + xmlLog.get("cardid")+", 文件名：" + fileName);
				return "2";
			}
			//1.模板全路径
			composeLog.put("wfd", template.getStorpath());	
			//2.数据模块名称
			billStencilSub.setStencilno(template.getId());
			String listname = billStencilDao.getMinStencilSubName(billStencilSub);
			if(null == listname) {
				log.debug("数据模块查询异常。==>>模板ID："+template.getId()+", 文件名："+fileName);
				return "3";
			}
			xmlData.put("dif1", listname);			
			//3.数据模块全路径
			xmlData.put("dif2", fileName);	
			//4.数据模板对象
			composeLog.put("dif", xmlData);					
			//5.防火区目录
			String matterpath = makeXmlDao.getConfig().get("MATTERPATH");
			if(null == matterpath) {
				log.debug("防火区配置目录查询异常。==>>文件名："+fileName);
				return "9";
			}
			composeLog.put("matterPath", matterpath);	
			//6.打印类型，正常0
			composeLog.put("printFlag", 0);								
			//7.电子账单标题
			String emailtitle = makeXmlDao.getConfig().get("EMAILTITLE");
			if(null == emailtitle) {
				log.debug("电子账单标题查询异常。==>>文件名："+fileName);
				return "10";
			}
			composeLog.put("EmailTitle", emailtitle);					
			//8.输出类型，HTML
			composeLog.put("e", CommandMaker.OUTPUT_TYPE_HTML);			
			//9.HTML生成路径，不带后缀，为生成索引文件准备  HTML_xxxX_xxxx_xxx
			String fn = fileName;
			filepath = fileName.replace(".xml", "").replace("/HTML", "").replace("/XML/", "/HTML/");
			fn = filepath.substring(0, filepath.lastIndexOf("/")+1);
			File f = new File(fn);
			if(!f.exists()) {
				f.mkdirs();
			}
			htmlMap.put(fileName, fn);
			composeLog.put("productionPath", filepath);
			//10.HTML生成路径，带后缀(.html)
			composeLog.put("f", filepath + "_%06g.html");
			//11.job路径
			composeLog.put("c", template.getJobpath());
			//12.警告配置路径
			String warningpath = makeXmlDao.getConfig().get("WARNINGPATH");
			if(null == warningpath) {	//未查找到警告配置路径，打印日志并修改Xml状态
				log.debug("警告配置路径查询异常。==>>文件名："+fileName);
				return "6";
			}
			composeLog.put("warningconfig", warningpath);
			eCompose.add(composeLog);
		} else {	//实体纸质账单对象构造
			image_flag = true;
			template.setType("1");
			template = templateDao.getObject(template);
			if(null == template) {
				log.debug("模板查询异常。==>>卡产品："+xmlLog.get("cardid")+", 文件名："+fileName);
				return "2";
			}
			//1.模板全路径
			composeLog.put("wfd", template.getStorpath());	
			//2.数据模块名称
			billStencilSub.setStencilno(template.getId());
			String listname = billStencilDao.getMinStencilSubName(billStencilSub);
			if(null == listname) {
				log.debug("数据模块查询异常。==>>模板ID："+template.getId()+", 文件名："+fileName);
				return "3";
			}
			xmlData.put("dif1", listname);			
			//3.数据模块全路径
			xmlData.put("dif2", fileName);	
			//4.数据模板对象
			composeLog.put("dif", xmlData);					
			//5.外包商打印类型
			paperCityCrd.setCard_no(xmlLog.get("cardid"));
			paperCityCrd.setBusinpnt_no(xmlLog.get("epibolyno"));
			List<PaperCityCrd> lp = epibCityDao.getList(paperCityCrd, 0, 1);
			if(null == lp) {
				log.debug("外包商打印类型查询异常。==>>卡产品ID："+xmlLog.get("cardid")+", 外包商ID："
						+xmlLog.get("epibolyno")+", 文件名："+fileName);
				return "4";
			}
			paperCityCrd = lp.get(0);
			composeLog.put("printMode", paperCityCrd.getPrint_type());	
			//6.打印类型，正常0
			composeLog.put("printFlag", 0);								
			//7.模板标识，带底板1
			composeLog.put("templateFlag", 1);					
			//8.输出类型，PDF
			composeLog.put("e", CommandMaker.OUTPUT_TYPE_TNO);			
			//9.PDF生成路径，不带后缀，为生成索引文件准备
			filepath = fileName.replace(".xml", "").replace("/TNO", "").replace("/XML/", "/TNO/");
			composeLog.put("productionPath", filepath);
			//10.PDF生成路径，带后缀(.pdf)
			composeLog.put("f", filepath+".tno");
			//11.job路径
			String jobpath = makeXmlDao.getConfig().get("SPEC_JOB");
			if(null == jobpath) {
				log.debug("job路径查询异常。==>>文件名："+fileName);
				return "5";
			}
			composeLog.put("c", jobpath);
			//12.警告配置路径
			String warningpath = makeXmlDao.getConfig().get("WARNINGPATH");
			if(null == warningpath) {
				log.debug("警告配置路径查询异常。==>>文件名："+fileName);
				return "6";
			}
			composeLog.put("warningconfig", warningpath);
			//12.预印纸底板路径
			Map<String, String> prepPaperPath = new HashMap<String, String>();
			List<PaperInfo> listp = paperDao.queryPaperInfoBypaperNo(xmlLog.get("paperno"));
			int len3 = listp.size();
			if(len3 == 0) {
				log.debug("预印纸底板路径查询异常。==>>文件名："+fileName);
				return "7";
			}
			for(int k = 0; k < len3; k++) {
				String imagepath = listp.get(k).getFront();
				if("" == imagepath) {
					log.debug("预印纸底板路径查询异常。==>>预印纸编号："+listp.get(k).getId()+", 底板编号："+listp.get(k).getBg_no());
					image_flag = false;
					break;
				}
				prepPaperPath.put("prePaperPath"+(k+1), imagepath);
			}
			if(!image_flag){
				return "8";
			}
			composeLog.put("prePaperPath", prepPaperPath);
			pCompose.add(composeLog); 
		}
		updComposeState(logName, "2");
		/*
		//调用合成接口
		NetServerUtil nsu = null;
		NetServerFlowControl control = null;
		NetServerFlowInterface runnerFlow = null;
		NetServerConnection connectionItem = null;
		fileUtil = new FileUtil();
		int i = 0;
		if(null != eCompose) {		//电子账单传入参数
			nsu = new NetServerUtil(eCompose);
			i = 1;
		} else if(null != pCompose) {	//纸质账单传入参数
			nsu = new NetServerUtil(pCompose);
			i = 2;
		}
		//电子账单合成调用开始
		control = nsu.start();
		for(int j = 0; j < control.getNetServerFlowSize(); j++){
			runnerFlow = control.getNetServerFlow(j);
			connectionItem = runnerFlow.getNetServerConnection();
			boolean runSucc = runnerFlow.runSuccess();
			String resultState = "成功";
			if(!runSucc) {
				resultState = "失败";
				if(runnerFlow.lastJobMessage().contains("0030:Nothing to print.")) {
					log.debug("Nothing to print.fileindex flag write is [already pass]");
					resultState = "已过滤";
				}
			}
			String xmlFileName = runnerFlow.getNameItem("xmlName");
			//获取Xml数据名称
			log.debug("xml name is ==>>"+xmlFileName);
			//端口，job运行信息
			log.debug(connectionItem.getParameter("port")+"job run info ==>>"+runnerFlow.lastJobMessage());
			//修改XML状态未账单生产中
			xmlLog = new HashMap<String, String>();
			xmlLog.put("filename", xmlFileName);
			if("已过滤".equals(resultState)) {		//已过滤
				updComposeState(logName, "6");
			} else if("成功".equals(resultState)) {	//生成成功
				updComposeState(logName, "5");
				if(i == 1) {
					fileUtil.doZip(htmlMap.get(xmlFileName));
				}
			} else if("失败".equals(resultState)) {	//生成失败
				updComposeState(logName, "0");
			}
		}
		*/
		return "0";
	}
	
}
